package com.zwps.biz.domain.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zwps.biz.api.model.vo.forecast.DataSetVO;
import com.zwps.biz.api.model.vo.forecast.LatestForecastVO;
import com.zwps.biz.api.model.vo.forecast.RainfallForecastVO;
import com.zwps.biz.api.model.vo.pubpointall.CalculationVO;
import com.zwps.biz.dal.db.dao.PubPointAllDAO;
import com.zwps.biz.domain.service.ForecastService;
import com.zwps.common.api.model.vo.ForecastResultVO;
import com.zwps.common.core.exception.UserActionException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


@Service
@Slf4j
public class ForecastServiceImpl implements ForecastService {

    @Value("${application.auth.forecast-host}")
    String forecastHost;

    final int timeout = 10000;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    ApiService apiService;
    @Autowired
    PubPointAllDAO  pubPointAllDAO;

    public RainfallForecastVO getRainfallForecast()  {
        String DS_ID = "";
        // 请求获取唯一 DS_ID
        HttpRequest request = HttpUtil
                .createPost(forecastHost + "/hydro/scheme/read-latest-dataset").body("{\"SCHEME_ID\": \"HOUR_FLOOD_ONE_XAJ_FORE\"}").header("projectId", "486d81805f12450f9efd288ef9d60c51").header("Content-Type", ContentType.JSON.getValue());
        request.timeout(timeout);

        try (HttpResponse response = request.execute()) {
            log.info("read-latest-dataset 请求返回 {}", response.body());
            ForecastResultVO<DataSetVO> result =  objectMapper.readValue(response.body(), new TypeReference<ForecastResultVO<DataSetVO>>() {});
            DS_ID = result.getData().getDS_ID();
        } catch (Exception error) {
            log.info("read-latest-dataset 请求报错 {}", error.getMessage());
        }

        if(StrUtil.isEmpty(DS_ID)) {
            throw new UserActionException("DS_ID 查询结果不存在");
        }
        HashMap<String, Object> bodyMap = new HashMap<>();
        HashMap<String, Object> DT_COND_IDS = new HashMap<>();
        String[] DT_IDS = {"SC_AREA_RAIN","SC_RUNOFF_SELECT","SC_LEVEL_SELECT"};
//        String[] EQUAL_DATASET_PERIOD_SPOINTS = {"btime", ""};
        DT_COND_IDS.put("EQUAL_DATASET_ID", DS_ID);
        DT_COND_IDS.put("EQUAL_DATASET_OBJECT_TYPE", "FOS");
        DT_COND_IDS.put("EQUAL_DATASET_OBJECT_ID", "62901300");
//        DT_COND_IDS.put("EQUAL_DATASET_PERIOD_SPOINTS", EQUAL_DATASET_PERIOD_SPOINTS);
        DT_COND_IDS.put("EQUAL_DATASET_MODEL_SIGN", "XAJ");
        bodyMap.put("DT_IDS", DT_IDS);
        bodyMap.put("DT_COND_IDS", DT_COND_IDS);

        String bodyStr = JSON.toJSONString(bodyMap);
        HttpRequest request1 = HttpUtil
                .createPost(forecastHost + "/hydro/read/read-single-scheme-props-table")
                .header("projectId", "486d81805f12450f9efd288ef9d60c51").header("Content-Type", ContentType.JSON.getValue())
                .body(bodyStr)
        ;
        request1.timeout(timeout);

        try (HttpResponse response1 = request1.execute()) {
            log.info("read-single-scheme-props-table 请求返回 {}", response1.body());
            ForecastResultVO<RainfallForecastVO> result = objectMapper.readValue(response1.body(), new TypeReference<ForecastResultVO<RainfallForecastVO>>() {});
            return result.getData();
        } catch (Exception error) {
            log.info("read-single-scheme-props-table 请求报错 {}", error.getMessage());
            throw new UserActionException("查询失败" +  error.getMessage());
        }

    }
    public LatestForecastVO getLatestForecastResult() {
        String DS_ID = "";
        // 请求获取唯一 DS_ID
        HttpRequest request = HttpUtil
                .createPost(forecastHost + "/hydro/scheme/read-latest-dataset").body("{\"SCHEME_ID\": \"HOUR_FLOOD_ONE_XAJ_FORE\"}").header("projectId", "486d81805f12450f9efd288ef9d60c51").header("Content-Type", ContentType.JSON.getValue());
        request.timeout(timeout);

        try (HttpResponse response = request.execute()) {
            ForecastResultVO<DataSetVO> result =  objectMapper.readValue(response.body(), new TypeReference<ForecastResultVO<DataSetVO>>() {});
            DS_ID = result.getData().getDS_ID();
        } catch (Exception error) {
            System.out.println(error.getMessage());
        }

        if(StrUtil.isEmpty(DS_ID)) {
            throw new UserActionException("DS_ID 查询结果不存在");
        }
        HashMap<String, Object> bodyMap = new HashMap<>();
        HashMap<String, Object> DT_COND_IDS = new HashMap<>();
        String[] DT_IDS = {"SC_AREA_RAIN_SUM","SC_FORE_FLOOD_VOLUME","SC_FORE_PEAK_FLOW","SC_FORE_PEAK_TIME","SC_FORE_MAX_WL_TIME","SC_FORE_MAX_WL"};
        DT_COND_IDS.put("EQUAL_DATASET_ID", DS_ID);
        DT_COND_IDS.put("EQUAL_DATASET_OBJECT_TYPE", "FOS");
        DT_COND_IDS.put("EQUAL_DATASET_OBJECT_ID", "62901300");
        DT_COND_IDS.put("EQUAL_DATASET_MODEL_SIGN", "XAJ");
        bodyMap.put("DT_IDS", DT_IDS);
        bodyMap.put("DT_COND_IDS", DT_COND_IDS);

        String bodyStr = JSON.toJSONString(bodyMap);
        HttpRequest request1 = HttpUtil
                .createPost(forecastHost + "/hydro/read/read-single-scheme-props")
                .header("projectId", "486d81805f12450f9efd288ef9d60c51").header("Content-Type", ContentType.JSON.getValue())
                .body(bodyStr)
//                .body("{\"DT_IDS\":[\"SC_AREA_RAIN_SUM\", \"SC_FORE_FLOOD_VOLUME\", \"SC_FORE_PEAK_FLOW\",\"SC_FORE_PEAK_TIME\",\"SC_FORE_MAX_WL_TIME\", \"SC_FORE_MAX_WL\"],\"DT_COND_IDS\":{\"EQUAL_DATASET_ID\":\"" + DS_ID + "\",\"EQUAL_DATASET_OBJECT_TYPE\":\"FOS\",\"EQUAL_DATASET_OBJECT_ID\":\"62901300\",\"EQUAL_DATASET_MODEL_SIGN\":\"XAJ\"}}");
        ;
        request1.timeout(timeout);

        try (HttpResponse response1 = request1.execute()) {
            ForecastResultVO<LatestForecastVO> result = objectMapper.readValue(response1.body(), new TypeReference<ForecastResultVO<LatestForecastVO>>() {});
            return result.getData();
        } catch (Exception error) {
            throw new UserActionException("查询失败" +  error.getMessage());
        }
    }
    public Map<String, Object> getRehearsalPlanList(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        HashMap<String, Object> bodyMap = new HashMap<>();
        HashMap<String, Object> DT_COND_IDS = new HashMap<>();
        String st;
        String et;
        String[] DT_IDS = {"OP_INUND_REHEARSAL_INFO"};
        try {
            st = DateUtil.format(sdf.parse(startTime), "yyyy-MM-dd ");
            et = DateUtil.format(sdf.parse(endTime), "yyyy-MM-dd");
        } catch (ParseException e) {
            throw new UserActionException("时间传参格式错误");
        }

        DT_COND_IDS.put("GOE_TIME", st);
        DT_COND_IDS.put("LOE_TIME", et);
        DT_COND_IDS.put("EQUAL_ANY_TYPE", "ALL");
        bodyMap.put("pageRouter", "lhk/downstream-submergence-rehearsal");
        bodyMap.put("WCPID", "");
        bodyMap.put("prevResp", "");
        bodyMap.put("DT_IDS", DT_IDS);
        bodyMap.put("DT_COND_IDS", DT_COND_IDS);

        String bodyStr = JSON.toJSONString(bodyMap);
        HttpRequest request1 = HttpUtil
                .createPost(forecastHost + "/hydro/read/read-single-scheme-props")
                .header("projectId", "486d81805f12450f9efd288ef9d60c51").header("Content-Type", ContentType.JSON.getValue())
                .body(bodyStr)
//                .body("{\"DT_IDS\":[\"SC_AREA_RAIN_SUM\", \"SC_FORE_FLOOD_VOLUME\", \"SC_FORE_PEAK_FLOW\",\"SC_FORE_PEAK_TIME\",\"SC_FORE_MAX_WL_TIME\", \"SC_FORE_MAX_WL\"],\"DT_COND_IDS\":{\"EQUAL_DATASET_ID\":\"" + DS_ID + "\",\"EQUAL_DATASET_OBJECT_TYPE\":\"FOS\",\"EQUAL_DATASET_OBJECT_ID\":\"62901300\",\"EQUAL_DATASET_MODEL_SIGN\":\"XAJ\"}}");
                ;
        request1.timeout(timeout);

        try (HttpResponse response1 = request1.execute()) {
            Map<String, Object> result = objectMapper.readValue(response1.body(), new TypeReference<Map<String, Object>>() {});
            return (Map<String, Object>) result.get("data");
        } catch (Exception error) {
            throw new UserActionException("查询失败" +  error.getMessage());
        }
    }
    @Override
    public Map<String, Object> getRealTimeRain() {
        String requestBody = "{\n" +
                "    \"DT_IDS\": [\n" +
                "        \"OP_PREDICTION_REALTIME_RAIN\"\n" +
                "    ],\n" +
                "    \"DT_COND_IDS\": {}\n" +
                "}";
        return callAndParseApi(requestBody, "调用降雨数据API失败", "解析降雨数据响应失败");
    }

    @Override
    public Map<String, Object> getRealTimeWater() {
        String requestBody = "{\"DT_IDS\":[\"OP_PREDICTION_REALTIME_WATER\"],"
                + "\"DT_COND_IDS\":{\"FUNC_ID\":\"HOUR_FLOOD_ONE_XAJ_FORE\","
                + "\"DATA_ID\":\"SC_XAJ_FORE_LEVEL\"}}";
        return callAndParseApi(requestBody, "调用水情数据API失败", "解析水情数据响应失败");
    }
    @Override
    public Map<String, Object> getFloodDsp() {
        String requestBody = "{\n" +
                "    \"DT_IDS\": [\n" +
                "        \"OP_PREDICTION_REALTIME_WATER\"\n" +
                "    ],\n" +
                "    \"DT_COND_IDS\": {\n" +
                "        \"FUNC_ID\": \"HOUR_FLOOD_DSP \",\n" +
                "        \"DATA_ID\": \"RP_OUTFLOW\"\n" +
                "    }\n" +
                "}";
        return callAndParseApi(requestBody, "下泄实时预报API失败", "解析下泄实时预报响应失败");
    }


    private Map<String, Object> callAndParseApi(String requestBody, String apiErrorMsg, String parseErrorMsg) {
        String apiResponse;
        try {
            apiResponse = apiService.wcpByPost("/hydro/read/read-single-object-props", requestBody);
        } catch (Exception e) {
            throw new RuntimeException(apiErrorMsg, e);
        }

        try {
            Map<String, Object> responseMap = objectMapper.readValue(apiResponse,
                    new TypeReference<Map<String, Object>>() {});
            return Optional.ofNullable(responseMap.get("data"))
                    .filter(data -> data instanceof Map)
                    .map(data -> (Map<String, Object>) data)
                    .orElse(Collections.emptyMap());
        } catch (JsonProcessingException e) {
            throw new RuntimeException(parseErrorMsg, e);
        }
    }

    @Override
    public List<CalculationVO> getBriefWaring() {
        List<CalculationVO> briefWaring = pubPointAllDAO.getBriefWaring();


        return briefWaring;
    }

    @Override
    public Map<String, Object> getHisTimeRain() {
        String requestBody = "{\n" +
                "    \"DT_IDS\": [\n" +
                "        \"OP_PREDICTION_HIS_RAIN\"\n" +
                "    ],\n" +
                "    \"DT_COND_IDS\": {}\n" +
                "}\n";
        return callAndParseApi(requestBody, "调用降雨数据API失败", "解析降雨数据响应失败");
    }

    @Override
    public Map<String, Object> getHisTimeWater() {
        String requestBody = "{\n" +
                "    \"DT_IDS\": [\n" +
                "        \"OP_PREDICTION_HIS_WATER\"\n" +
                "    ],\n" +
                "    \"DT_COND_IDS\": {\n" +
                "        \"FUNC_ID\": \"HOUR_FLOOD_ONE_XAJ_FORE\",\n" +
                "        \"DATA_ID\": \"SC_XAJ_FORE_LEVEL\"\n" +
                "    }\n" +
                "}";
        return callAndParseApi(requestBody, "调用水情数据API失败", "解析水情数据响应失败");
    }
    @Override
    public Map<String, Object> getHisFloodDsp() {
        String requestBody = "{\n" +
                "    \"DT_IDS\": [\n" +
                "        \"OP_PREDICTION_HIS_WATER\"\n" +
                "    ],\n" +
                "    \"DT_COND_IDS\": {\n" +
                "        \"FUNC_ID\": \"HOUR_FLOOD_DSP \",\n" +
                "        \"DATA_ID\": \"RP_OUTFLOW\"\n" +
                "    }\n" +
                "}";
        return callAndParseApi(requestBody, "下泄历史预报API失败", "解析下泄历史预报响应失败");
    }
}
